#include "usart5.h"

#define T_F 0

#define USART2_TX_BUFFER_SIZE 0
#define USART2_RX_BUFFER_SIZE 20U

void dma_configuration(void);
u8 Uart5_RXBUF[UART5_BUFLEN];
uint16_t Uart5_Index;
_GPS_Module Gps_Module, Flag_GpsRxModule;




/************GPS***********************/

/*********使用DMA*******************/
void Uart5Dma_Init(uint32_t bound)
{
  gpio_init_type gpio_init_struct;
  dma_init_type dma_init_struct;
  
  crm_periph_clock_enable(CRM_UART5_PERIPH_CLOCK, TRUE);   //开启USART1的时钟
	crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(UART5_GPIO_CRM_CLK, TRUE);

  gpio_default_para_init(&gpio_init_struct);

  /* configure the usart2 tx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = UART5_TX_PIN|UART5_RX_PIN;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(UART5_GPIO, &gpio_init_struct);

	gpio_pin_mux_config(UART5_GPIO, GPIO_PINS_SOURCE5, UART5_PIN_MUX_NUM);//复用IO为串口接收
	gpio_pin_mux_config(UART5_GPIO, GPIO_PINS_SOURCE6, UART5_PIN_MUX_NUM);//服用IO为串口发送


	//DMA基础配置
  crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
  dmamux_enable(DMA1, TRUE);//启用或禁用 DMAMUX。
  dma_reset(DMA1_CHANNEL4);
  dma_default_para_init(&dma_init_struct);
  dma_init_struct.buffer_size = UART5_BUFLEN;                     					//内存大小
  dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;                	//外设地址为目的地址
  dma_init_struct.memory_base_addr = (uint32_t)&Uart5_RXBUF;                          //内存地址
  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;          	//内存数据的宽度 8bit
  dma_init_struct.memory_inc_enable = TRUE;                                	//内存地址递增打开
  dma_init_struct.peripheral_base_addr = (uint32_t)&UART5->dt;            	//外设地址
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;  	//外设数据的宽度 8bit
  dma_init_struct.peripheral_inc_enable = FALSE;                           	//外设地址递增关闭
  dma_init_struct.priority = DMA_PRIORITY_MEDIUM;                          	//中等优先级
  dma_init_struct.loop_mode_enable = TRUE;                                	//使能
  dma_init(DMA1_CHANNEL4, &dma_init_struct);

	dma_flexible_config(DMA1,DMA1MUX_CHANNEL4,DMAMUX_DMAREQ_ID_UART5_RX);  //DMA1的通道2设定为串口2的DMA接收通道
	usart_dma_receiver_enable(UART5, TRUE);                           //使能DMA接收
	dma_channel_enable(DMA1_CHANNEL4, TRUE); 													// usart2 rx 开始 DMA 接收 

	
	
	//USART2配置
	nvic_irq_enable(UART5_IRQn, usart5_preempt_priority, usart5_sub_priority);                               	//使能串口1终端，优先级0，次优先级0
	/* configure usart2 param */
  usart_init(UART5, 115200, USART_DATA_8BITS, USART_STOP_1_BIT);
  usart_transmitter_enable(UART5, TRUE);
  usart_receiver_enable(UART5, TRUE);
  usart_interrupt_enable(UART5, USART_IDLE_INT, TRUE);
  usart_enable(UART5, TRUE);

}
//DMA IRQ handle
//void UART5_IRQHandler(void)
//{
//	 uint8_t clear;
//	
//	 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
//	
//	 if(usart_flag_get(UART5, USART_IDLEF_FLAG) != RESET)                   // USART5总线空闲
//		 {
//			 usart_data_receive(UART5);  																				//clear idle flag;
//			 dma_channel_enable(DMA1_CHANNEL4, FALSE);     											//关闭DMA通道
//			 usart_flag_clear(UART5,USART_IDLEF_FLAG);
//			 usart_dma_receiver_enable(UART5, FALSE);         									//关闭USART1 DMA 接收
//			 dma_data_number_set(DMA1_CHANNEL4, UART5_BUFLEN);
//			 xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//		 }
//}

/******不使用DMA********/
void Uart5_Init(uint32_t bound)
{
  gpio_init_type gpio_init_struct;
  
  crm_periph_clock_enable(CRM_UART5_PERIPH_CLOCK, TRUE);   //开启USART1的时钟
	crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(UART5_GPIO_CRM_CLK, TRUE);

  gpio_default_para_init(&gpio_init_struct);

  /* configure the usart2 tx pin */
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = UART5_TX_PIN|UART5_RX_PIN;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(UART5_GPIO, &gpio_init_struct);

	gpio_pin_mux_config(UART5_GPIO, GPIO_PINS_SOURCE5, UART5_PIN_MUX_NUM);//复用IO为串口接收
	gpio_pin_mux_config(UART5_GPIO, GPIO_PINS_SOURCE6, UART5_PIN_MUX_NUM);//服用IO为串口发送

	//USART2配置
	nvic_irq_enable(UART5_IRQn, usart5_preempt_priority, usart5_sub_priority);                               	//使能串口1终端，优先级0，次优先级0
	/* configure usart2 param */
  usart_init(UART5, bound, USART_DATA_8BITS, USART_STOP_1_BIT);
  usart_transmitter_enable(UART5, TRUE);
  usart_receiver_enable(UART5, TRUE);
  usart_interrupt_enable(UART5, USART_RDBF_INT, TRUE);
  usart_enable(UART5, TRUE);

}

const char srt_GNGGA[]= {"GNGGA"}; 
const char str_GNRMC[]= {"GNRMC"}; 
const char str_GpsModuleEnd[] = {"\r\n"};
uint8_t str_GNGGA_Index,str_GNRMC_Index;
uint8_t str_GpsModuleEnd_Index;

/*
void UART5_IRQHandler(void)
{
	 uint8_t clear;
	 static uint8_t state_GNGGA=0,state_GNRMC = 0;
	
	 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	
	 if(usart_flag_get(UART5, USART_RDBF_FLAG) != RESET)                   // USART5总线空闲
	 {
	 
			
			usart_flag_clear(UART5,USART_RDBF_FLAG);
		 
		 //接收一个字节
			Uart5_RXBUF[Uart5_Index] = (UART5->dt);
		 
		 //找 GNGGA 包开始
			if(FindString(srt_GNGGA,&str_GNGGA_Index,strlen(srt_GNGGA),Uart5_RXBUF[Uart5_Index]))
			{
				Uart5_RXBUF[0] = '$';
				Uart5_RXBUF[1] = 'G';
				Uart5_RXBUF[2] = 'N';
				Uart5_RXBUF[3] = 'G';
				Uart5_RXBUF[4] = 'G';
				Uart5_RXBUF[5] = 'A';
				
				Uart5_Index = 5;
				Gps_Module = Module_$GNGGA;
			}
			
			//找 GNRMC
			if(FindString(str_GNRMC,&str_GNRMC_Index,strlen(str_GNRMC),Uart5_RXBUF[Uart5_Index]))
			{
				Gps_Module = Module_$GNRMC;
			}
		
			//判断一个包接收结束
			switch(Gps_Module)
			{
				case Module_$GPGSV:
					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
					{
						Flag_GpsRxModule = Module_$GPGSV;
					}
					break;
				
				case Module_$GBGSV:
					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
					{
						Flag_GpsRxModule = Module_$GBGSV;
					}
					break;

				case Module_$GNGGA:
					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
					{
						Flag_GpsRxModule = Module_$GNGGA;
						state_GNGGA = 1;
					}
					
					if(state_GNGGA ==1 && state_GNRMC == 1)
					{
						state_GNGGA=0;
						state_GNRMC = 0;
						Flag_GpsRxModule = Module_IDLE;
						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
					}
					break;
				
				case Module_$GNGSA:
					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
					{
						Flag_GpsRxModule = Module_$GNGSA;
					}
					break;

				case Module_$GNRMC:
					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
					{
						Flag_GpsRxModule = Module_$GNRMC;
						state_GNRMC = 1;
					}
					if(state_GNGGA ==1 && state_GNRMC == 1)
					{
						state_GNGGA=0;
						state_GNRMC = 0;
						Flag_GpsRxModule = Module_IDLE;
						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
					}
					break;

				case Module_$GNVTG:
					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
					{
						Flag_GpsRxModule = Module_$GNVTG;
					}
					break;
				
				default:
					break;
			}

			//循环指针
			Uart5_Index++;
			if(Uart5_Index>=(UART5_BUFLEN-1))
				 Uart5_Index = 0;
		 }
}
*/



void UART5_IRQHandler(void)
{
	 uint8_t clear;
	
	 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
	
	 if(usart_flag_get(UART5, USART_RDBF_FLAG) != RESET)                   // USART5总线空闲
	 {
			usart_flag_clear(UART5,USART_RDBF_FLAG);
		 
		 //接收一个字节
			Uart5_RXBUF[Uart5_Index] = (UART5->dt);
		 
		 //找 GNGGA
			if(FindString(srt_GNGGA,&str_GNGGA_Index,strlen(srt_GNGGA),Uart5_RXBUF[Uart5_Index]))
			{
					if(Flag_GpsRxModule != Module_IDLE)
					{
						Uart5_RXBUF[0] = '$';
						Uart5_RXBUF[1] = 'G';
						Uart5_RXBUF[2] = 'N';
						Uart5_RXBUF[3] = 'G';
						Uart5_RXBUF[4] = 'G';
						Uart5_RXBUF[5] = 'A';
						
						Uart5_Index = 5;
					}
				Gps_Module = Module_$GNGGA;
			}
					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
					{
						Flag_GpsRxModule = Module_$GNGGA;
						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
					}


			Uart5_Index++;
			if(Uart5_Index>=(UART5_BUFLEN-1))
				 Uart5_Index = 0;
			

			 
		 }
}





//void UART5_IRQHandler(void)
//{
//	 uint8_t clear;
//	
//	 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
//	
//	 if(usart_flag_get(UART5, USART_RDBF_FLAG) != RESET)                   // USART5总线空闲
//	 {
//	 
//			
//			usart_flag_clear(UART5,USART_RDBF_FLAG);
//			//usart_data_receive(UART5);  																				//clear idle flag;
//		 
//		 //接收一个字节
//			Uart5_RXBUF[Uart5_Index] = (UART5->dt);
//		 
//		 //找 GNGGA
//			if(FindString(srt_GNGGA,&str_GNGGA_Index,strlen(srt_GNGGA),Uart5_RXBUF[Uart5_Index]))
//			{
//					if(Flag_GpsRxModule != Module_IDLE)
//					{
//						Uart5_RXBUF[0] = '$';
//						Uart5_RXBUF[1] = 'G';
//						Uart5_RXBUF[2] = 'N';
//						Uart5_RXBUF[3] = 'G';
//						Uart5_RXBUF[4] = 'G';
//						Uart5_RXBUF[5] = 'A';
//						
//						Uart5_Index = 5;
//					}
//				Gps_Module = Module_$GNGGA;
//			}
//			
//			//找 GNRMC
//			if(FindString(str_GNRMC,&str_GNRMC_Index,strlen(str_GNRMC),Uart5_RXBUF[Uart5_Index]))
//			{
//				 if(Flag_GpsRxModule != Module_IDLE)
//					{
//						Uart5_RXBUF[0] = '$';
//						Uart5_RXBUF[1] = 'G';
//						Uart5_RXBUF[2] = 'N';
//						Uart5_RXBUF[3] = 'R';
//						Uart5_RXBUF[4] = 'M';
//						Uart5_RXBUF[5] = 'C';
//						
//						Uart5_Index = 5;
//					}
//				Gps_Module = Module_$GNRMC;
//			}
//		
//			switch(Gps_Module)
//			{
//				case Module_$GPGSV:
//					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
//					{
//						Flag_GpsRxModule = Module_$GPGSV;
//						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//					}
//					break;
//				
//				case Module_$GBGSV:
//					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
//					{
//						Flag_GpsRxModule = Module_$GBGSV;
//						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//					}
//					break;

//				case Module_$GNGGA:
//					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
//					{
//						Flag_GpsRxModule = Module_$GNGGA;
//						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//					}
//					break;
//				
//				case Module_$GNGSA:
//					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
//					{
//						Flag_GpsRxModule = Module_$GNGSA;
//						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//					}
//					break;

//				case Module_$GNRMC:
//					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
//					{
//						Flag_GpsRxModule = Module_$GNRMC;
//						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//					}
//					break;

//				case Module_$GNVTG:
//					if(FindString(str_GpsModuleEnd,&str_GpsModuleEnd_Index,strlen(str_GpsModuleEnd),Uart5_RXBUF[Uart5_Index]))
//					{
//						Flag_GpsRxModule = Module_$GNVTG;
//						xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//					}
//					break;
//				
//				default:
//					break;
//			}

//			Uart5_Index++;
//			if(Uart5_Index>=(UART5_BUFLEN-1))
//				 Uart5_Index = 0;
//			

//			 
//			 //xSemaphoreGiveFromISR(Usart5_sem,&xHigherPriorityTaskWoken);				//发送信号量
//		 }
//}


void Iint_GPS_Send(void)
{
	Uart5Send(GLL_OFF,MyStrlen(GLL_OFF));
	delay_ms(5);

	Uart5Send(GSA_OFF,MyStrlen(GSA_OFF));
	delay_ms(5);

	Uart5Send(GSV_OFF,MyStrlen(GSV_OFF));
	delay_ms(5);

	Uart5Send(VTG_OFF,MyStrlen(VTG_OFF));
	delay_ms(5);

	Uart5Send(ZDA_OFF,MyStrlen(ZDA_OFF));
	delay_ms(5);

	Uart5Send(GST_OFF,MyStrlen(GST_OFF));
	delay_ms(5);
	
	Uart5Send(GNTXT_OFF,MyStrlen(GNTXT_OFF));
	delay_ms(5);

	Uart5Send(RMC_ON,MyStrlen(RMC_ON));
	delay_ms(5);

	Uart5Send(GPS_GGA_ON,MyStrlen(GPS_GGA_ON));
	delay_ms(5);
	Uart5Send(GPS_SAVE,MyStrlen(GPS_SAVE));
}


void Uart5Send(uint8_t *buff,uint8_t size)
{
	uint8_t *Enter_click = buff;
	
	for (uint8_t uart5_tx_cnt = 0; uart5_tx_cnt < size; uart5_tx_cnt++)
	{
		while (usart_flag_get(UART5, USART_TDBE_FLAG) == RESET)
			;
		usart_data_transmit(UART5, Enter_click[uart5_tx_cnt]);
		while (usart_flag_get(UART5, USART_TDC_FLAG) == RESET)
			;
	}
}




